package com.ryder.petmatediarybackend.module.auth.consumer;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.rabbitmq.client.Channel;
import com.ryder.petmatediarybackend.common.config.mq.RabbitMQConfig;
import com.ryder.petmatediarybackend.module.auth.entity.AuthBlacklist;
import com.ryder.petmatediarybackend.module.auth.mapper.AuthBlacklistMapper;
import com.ryder.petmatediarybackend.module.auth.message.BlacklistSyncMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collections;

/**
 * 描述: 黑名单同步消费者（监听 RabbitMQ → 写入数据库）
 *
 * @author Ryder
 * @version 1.0
 * @since 1.0
 * 更新日期: 2025/10/28
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class BlacklistSyncConsumer {

    private final AuthBlacklistMapper authBlacklistMapper;

    /**
     * 监听黑名单同步队列（使用 INSERT IGNORE 避免重复）
     */
    @RabbitListener(queues = RabbitMQConfig.BLACKLIST_SYNC_QUEUE)
    public void consumeBlacklistSync(BlacklistSyncMessage message, Channel channel, Message amqpMessage) {
        try {
            log.debug("接收到黑名单同步消息：token={}", message.getToken());

            // 转换为 Entity
            AuthBlacklist authBlacklist = new AuthBlacklist();
            BeanUtils.copyProperties(message, authBlacklist);
            
            // 手动生成雪花 ID（因为使用自定义 SQL，MyBatis-Plus 不会自动填充）
            authBlacklist.setId(IdWorker.getId());

            // 使用 INSERT IGNORE 插入（忽略重复）
            authBlacklistMapper.batchInsertIgnore(Collections.singletonList(authBlacklist));

            // 手动确认消息
            channel.basicAck(amqpMessage.getMessageProperties().getDeliveryTag(), false);
            log.debug("黑名单同步成功：token={}", message.getToken());

        } catch (Exception e) {
            log.error("黑名单同步失败：token={}", message.getToken(), e);
            try {
                // 拒绝消息并重新入队（最多重试3次）
                channel.basicNack(amqpMessage.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                log.error("拒绝消息失败", ioException);
            }
        }
    }
}
